package com.tengju.motivation.domain.model.activity;

import com.tengju.motivation.domain.model.goods.Goods;
import com.tengju.motivation.domain.model.goods.GoodsType;
import com.tengju.motivation.domain.shared.DomainException;
import com.tengju.motivation.domain.shared.DomainExceptionCode;
import com.tengju.motivation.domain.shared.Entity;
import lombok.NonNull;
import lombok.Value;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Value
public class ActivityTarget implements Entity<ActivityTarget> {
    /**
     * 活动目标ID
     */
    TargetId targetId;
    /**
     * 活动ID
     */
    @NonNull
    ActivityId activityId;
    /**
     * 活动日期
     */
    @NonNull
    LocalDateTime activityTime;
    /**
     * 活动目标名称
     */
    String targetTitle;
    /**
     * 活动目标值
     */
    Long targetValue;
    /**
     * 活动目标类型
     */
    ActivityTargetType targetType;
    /**
     * 活动目标主体类型
     */
    @NonNull
    GoodsType targetSubjectType;
    /**
     * 活动目标主体ID
     */
    @NonNull
    Long targetSubjectId;
    /**
     * 活动目标参考开始日期
     */
    LocalDateTime targetReferStartTime;
    /**
     * 活动目标参考结束日期
     */
    LocalDateTime targetReferEndTime;
    /**
     * 活动目标对标主体类型
     */
    GoodsType targetCompareSubjectType;
    /**
     * 活动目标对标主体
     */
    List<Goods> targetCompareSubjects;

    public boolean isValid() {
        return targetValue == null || targetValue > 0;
    }

    /**
     * 校验活动是否进行中
     * startDate <= activityDate < endDate
     */
    public boolean isInProgress(LocalDateTime startTime, LocalDateTime endTime) {
        LocalDate startDate = startTime.toLocalDate();
        LocalDate endDate = endTime.toLocalDate();
        LocalDate activityDate = activityTime.toLocalDate();
        return(activityDate.isEqual(startDate) || activityDate.isAfter(startDate))
                && (activityDate.isEqual(endDate) ||activityDate.isBefore(endDate));
    }
    public ActivityTarget(TargetId targetId, @NonNull ActivityId activityId, @NonNull LocalDateTime activityTime,
                          String targetTitle, Long targetValue, ActivityTargetType targetType,
                          @NonNull GoodsType targetSubjectType, @NonNull Long targetSubjectId,
                          LocalDateTime targetReferStartTime, LocalDateTime targetReferEndTime,
                          GoodsType targetCompareSubjectType, List<Goods> targetCompareSubjects) {
        if (targetValue == null || targetType == null) {
            throw DomainException.error(DomainExceptionCode.ACTIVITY_TARGET_INFO_EMPTY);
        }
        this.targetId = targetId;
        this.activityId = activityId;
        this.activityTime = activityTime;
        this.targetTitle = targetTitle;
        this.targetValue = targetValue;
        this.targetType = targetType;
        this.targetSubjectType = targetSubjectType;
        this.targetSubjectId = targetSubjectId;
        this.targetReferStartTime = targetReferStartTime;
        this.targetReferEndTime = targetReferEndTime;
        this.targetCompareSubjectType = targetCompareSubjectType;
        this.targetCompareSubjects = targetCompareSubjects;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ActivityTarget target = (ActivityTarget) o;
        return sameIdentityAs(target);
    }

    @Override
    public int hashCode() {
        return Objects.hash(targetId);
    }

    @Override
    public boolean sameIdentityAs(ActivityTarget o) {
        if (this == o) return true;
        if (o == null) return false;
        if (this.getTargetId() == null) {
            return this.getActivityId().sameValueAs(o.getActivityId())
                    && this.getActivityTime().equals(o.getActivityTime())
                    && this.getTargetSubjectId().equals(o.getTargetSubjectId());
        } else {
            return this.getTargetId().sameValueAs(o.getTargetId());
        }
    }
}
